#Constructs the Environment object. This object extends RAgent, so
#its variables and methods are also available to this object 
setConstructorS3("AEnvironment", function() {
	# Extends RAgent object
	extend(RAgent(), "AEnvironment",
	 	.cells = list(), #Used to store the cell objects. More intuitive than using the RAgents .li list
		.agents = "",    #Used to store the list of agent types to be stored in each cell
		.depth = "",     #Depth object that may be used when agents make decisions
		.temp = "",      #Temperature object that may be used when agents make decisions
		.bottom = ""     #Bottom object that may be used when agents make decisions
		#Further nessesary environmental objects should be declared here
	)   
})

#This method creates the cell objects based on the data provided to the environment
#The cell divisions are made by getting the supplied environment geography and dividing it into
#the supplied resolution celsiz. The agents supplied in the includeAgents method are added to 
#each cell in the manner defined in the particular agents create methods.
setMethodS3("generateCells", "AEnvironment", function(this, celsiz) {
	
	down = 0 #Keep track of upper row boudary
	cellhei = celsiz[2] #The height of each cell 
	celllen = celsiz[1] #The width of each cell
	i = 1 #Variable used to loop through each row 
	#While loop to visit each row
	while(down < this$totheight()){
		over = 0 #Keep track of column, sets back to zero after new row has bee entered
        j = 1 	#Variable used to loop through each column in a row 		
		this$.cells[[i]] = list() #Create a new list at this new row to store each column cell. 
		                          #This allows for a two dimensional list to be created.
        #While loop to visit each column in this row								  
		while(over < this$totlength()){
            
			#Create a cell object that will stored at this location, its parent is this environment, its
			#gridloc is its location in this$.cells
			newcel = ACell(parent = this, gridloc = c(i, j))
			#Create the cells geography boundary
			matbound = matrix(c(over, over, over + celllen, over + celllen, over,  down, down + cellhei, down + cellhei, down, down), ncol = 2, nrow = 5)
			newcel$setgeo(matbound)
			#Call the new cells populate function and give it the list of desired agents at this cell
		    newcel$populate(this$.agents)
			
			this$.cells[[i]][[j]] = newcel #Store the newly created cell
			print(paste("Cell ," , i, " ,", j, "Created.")) #Tell user that the cell has been created. May want to commment out, to gain speed
			
			over = over + celllen #Move to the beginning of the next column
			j = j + 1 #Move the cell location to next column position
		}
		
		down = down + cellhei #Move to the beginning of the next row
		i = i + 1 #Move the cell location to next row position
		
	}
	
	
})
#ALL CURRENT ENVIROMNTAL DATA WERE CREATED RANDOMLY WITH 10 by 10 RESOLUTION TO
#MAP EASLIY WITH THIS SIMULATIONS TESTING CONSTRUCT
#This method creates the environmental objects. Be sure to include any newly defined 
#Objects in the start.r source list and add a variable in this constructor so that they can be later referenced
setMethodS3("includeEnvironmentals", "AEnvironment", function(this, envirolis) {
	#For each entry in the list, match and create. 
	for(i in 1:length(envirolis)){
		if(envirolis[i] == "depth")
			this$.depth = ADepth(read.table(file.path( rootdir, c("depth.txt"))))
		if(envirolis[i] == "temp")
			this$.temp = ATemp(read.table(file.path( rootdir, c("temp.txt"))))
		if(envirolis[i] == "bottom")
			this$.bottom = ABottom(read.table(file.path( rootdir, c("bottom.txt"))))
		}
		#Add more matches and object creations here
})

#Method that set the gents to be included
setMethodS3("includeAgents", "AEnvironment", function(this, agentlis) {
	this$.agents = agentlis
		
})

#This method is called after the cells have been set up. Every day t loops through each column of 
#each row telling the cell that a day has passed. The cell then follows is onw rules once this
#information is available to it
setMethodS3("beginsim", "AEnvironment", function(this, ndays) {
print("Begin Sim of days")
	for(i in 1:ndays){ #For each day
		this$.updated = this$.updated * -1 #Mark the day as new
		for(i in 1:length(this$.cells)){ #For each row 
			for(j in 1:length(this$.cells[[i]])){ #For each column cell
		        #The environment sends a plusDay command to the cell at the location via RAgents send function
				#The send function will pass the command to the cell objects do function
				this$send("plusDay", this$.cells[[i]][[j]])	
			}
		}
	}
})